home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 11 / CU Amiga Magazine's Super CD-ROM 11 (1997)(EMAP Images)(GB)(Track 1 of 3)[!][issue 1997-06].iso / cucd / graphics / mpimage / si / miscmpi.c < prev    next >
C/C++ Source or Header  |  1997-03-14  |  15KB  |  656 lines

  1. // MPImage - Amiga Image Conversion
  2. // Copyright (C) © 1996 Mark John Paddock
  3. //
  4. // This program is free software; you can redistribute it and/or modify
  5. // it under the terms of the GNU General Public License as published by
  6. // the Free Software Foundation; either version 2 of the License, or
  7. // any later version.
  8.  
  9. // This program is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. // GNU General Public License for more details.
  13.  
  14. // You should have received a copy of the GNU General Public License
  15. // along with this program; if not, write to the Free Software
  16. // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17.  
  18. // mark@topic.demon.co.uk
  19. // mpaddock@cix.compulink.co.uk
  20.  
  21. /****** MPImage.library/--background-- ******************************
  22. *
  23. * Version 7.3 - fixed enforcer hit when no progress requester.
  24. *             - Opens locale.library(38) to work on OS3.0.
  25. *
  26. * MPImage.library lets you load save and process images.
  27. *
  28. * Stuctures/Formats:
  29. *
  30. *  RGB Chunky    This is held as seperate Red Green and Blue
  31. *                UBYTE *, with a Width and Height
  32. *  Grey Chunky   This is held as one Grey UBYTE * (often called
  33. *                red), with a Width and a Height.
  34. *  Palette       This is held as one UBYTE[768] (sometimes called
  35. *                red, a Width and Height, and a UBYTE *Palette. The
  36. *                palette holds the red palette in [0] to [255],
  37. *                the green palette in [256] to [511] and the blue
  38. *                palette in [512] to [767]. There may also be a
  39. *                camg (or modeid) and a number of colours, or
  40. *                number of planes. These are required for EHB and
  41. *                HAM images.
  42. *  Bitmap        A normal planar bit map. This also has other
  43. *                fields as for Palette.
  44. *  EGSBitMap     A standard EGSBitMap.
  45. *  MPImage       This holds one of RGB, Grey, Bitmap or EGSBitMap.
  46. *  MPProcess     This holds the RGB pointers and width and height.
  47. *                It is used for some processing functions.
  48. *
  49. * Image Loading:
  50. *
  51. *  LoadMPImage()   Loads an image from disc/clipboard.
  52. *                  It loads various formats.
  53. *                  Returns BitMap, RGB, GreyScale or EGSBitMap.
  54. *
  55. * Image Saving:
  56. *
  57. *  SaveMPImage()   Can save RGB/GreyScale to disc.
  58. *                  It saves in various formats.
  59. *
  60. * ImageScaling:
  61. *
  62. *  RescaleMPImage() Scales a loaded image (any format).
  63. *
  64. * Displaying Images
  65. *
  66. *  SaveMPImage()    Can display RGB/GreyScale Buffers.
  67. *
  68. * Miscellaneous:
  69. *
  70. *  FreeMPImage()         Frees a loaded image.
  71. *  SetMPImageScreen()    Sets the screen for the progress requester.
  72. *  MPProgressHook()      Sets a progress hook for messages.
  73. *  MPImageErrorMessage() Returns the last error message.
  74. *
  75. * Planar/Chunky Conversion:
  76. *
  77. *  MPPlanarToChunky() Converts a BitMap to a chunky buffer.
  78. *  MPChunkyToPlanar() Converts a chunky buffer to a BitMap.
  79. *  SaveMPImage()      Can convert RGB Buffers to a BitMap.
  80. *
  81. * Image processing:
  82. *
  83. *  Image processing is done on chunky buffers; RGB, GreyScale
  84. *  or Palette based. The following convert between these formats.
  85. *
  86. *  MPGreyToPal()  GreyScale to Palette.
  87. *  MPPalToGrey()  Palette to GreyScale.
  88. *  MPPalToPal()   Palette to a different Palette.
  89. *  MPPalToRGB()   Palette to RGB.
  90. *  MPRGBToGrey()  RGB To Grey.
  91. *  MPRGBToPal()   RGB To Palette.
  92. *
  93. *  Buffers can also be scaled:
  94. *
  95. *  MPScaleGrey()  Scales one buffer.
  96. *  MPScaleRGB()   Scales 3 buffers.
  97. *                 Same as 3 calls to MPScaleGrey() but faster.
  98. *
  99. * Summary:
  100. *
  101. * Input                            Output Format
  102. * Format   !Disc! RGB !Gray !Palette!BitMap!EGSBitMap!MPImage!Screen
  103. * ---------!----!-----!-----!-------!------!---------!-------!------
  104. * Disc/Clip!    !1*   !1*   !       !1*    !1*       !1      !
  105. * RGB      !2   !13,3*!10   !11     !2     !         !       !2
  106. * Gray     !2   !x    !12,3*!6      !2     !         !       !2
  107. * Palette  !    !9    !7    !8      !5     !         !       !
  108. * BitMap   !    !     !     !4      !3*,o  !         !       !
  109. * EGSBitMap!    !     !     !       !      !3*       !       !
  110. * MPImage  !2+  !+    !+    !#      !+     !+        !3      !2+
  111. *
  112. *  1 - LoadMPImage()
  113. *  2 - SaveMPImage()
  114. *  3 - RescaleMPImage()
  115. *  4 - MPPlanarToChunky()
  116. *  5 - MPChunkyToPlanar()
  117. *  6 - MPGreyToPal()
  118. *  7 - MPPalToGrey()
  119. *  8 - MPPalToPal()
  120. *  9 - MPPalToRGB()
  121. * 10 - MPRGBToGrey()
  122. * 11 - MPRGBToPal()
  123. * 12 - MPScaleGrey()
  124. * 13 - MPScaleRGB()
  125. *  * - As part of an MPImage
  126. *  + - Depends on parameters to LoadMPImage
  127. *  x - Easy - no function supplied
  128. *  o - See BitMapScale()
  129. *  # - Depends on LoadMPImage, use 11,6,8 or 4
  130. *
  131. *****************************************************************************
  132. *
  133. */
  134.  
  135. #define CATCOMP_BLOCK
  136. #define CATCOMP_NUMBERS
  137. #include "messages.h"
  138.  
  139. #include "mpimage.h"
  140.  
  141. extern struct Catalog *Catalog=NULL;
  142. extern struct Library *LocaleBase = NULL;
  143.  
  144. extern struct Library *DCTVBase = NULL;
  145.  
  146. #ifdef CYBER
  147. extern struct Library *CyberGfxBase = NULL;
  148. #endif
  149.  
  150. extern struct Library *EGSBase = NULL;
  151.  
  152. extern char ErrorMessage[256] = "";
  153.  
  154. extern long __oslibversion=39;
  155.  
  156. const char Version[]="$VER: MPImage.library"
  157. #ifdef MY040
  158.     "_040"
  159. #else
  160. #ifdef _M68060
  161.     "_060"
  162. #else
  163. #ifdef _M68881
  164.     "_881"
  165. #else
  166. #ifdef _M68020
  167.     "_020"
  168. #else
  169.     "_000"
  170. #endif
  171. #endif
  172. #endif
  173. #endif
  174.     " 7.5 (14.3.97)";
  175.  
  176. char
  177. *GetMg(UWORD message) {
  178.     LONG   *l;
  179.     UWORD  *w;
  180.     STRPTR  builtIn;
  181.  
  182.    l = (LONG *)CatCompBlock;
  183.  
  184.     while (*l != message)  {
  185.         w = (UWORD *)((ULONG)l + 4);
  186.         l = (LONG *)((ULONG)l + (ULONG)*w + 6);
  187.     }
  188.     builtIn = (STRPTR)((ULONG)l + 6);
  189.     return(GetCatalogStr(Catalog,message,builtIn));
  190. }
  191.  
  192. static far int OpenCount = 0;
  193. static far struct SignalSemaphore sema = {0};
  194.  
  195. static struct Hook *ProgressHook = NULL;
  196.  
  197. extern void
  198. SetMax(int max) {
  199.     if (ProgressWnd) {
  200.         GT_SetGadgetAttrs(ProgressGadgets[GDX_Progress],ProgressWnd,NULL,
  201.                             GTSL_Max,max-1,
  202.                             GTSL_Level,0,
  203.                             TAG_END);
  204.     }
  205.     if (ProgressHook) {
  206.         CallHookPkt(ProgressHook,MPIP_MAX,(APTR)max);
  207.     }
  208. }
  209.  
  210. extern void
  211. SetCur(int cur) {
  212.     if (ProgressWnd) {
  213.         GT_SetGadgetAttrs(ProgressGadgets[GDX_Progress],ProgressWnd,NULL,
  214.                             GTSL_Level,cur,
  215.                             TAG_END);
  216.     }
  217.     if (ProgressHook) {
  218.         CallHookPkt(ProgressHook,MPIP_CURR,(APTR)cur);
  219.     }
  220. }
  221.  
  222. void AddMessageNo(UWORD no) {
  223.     AddMessage(GetMg(no));
  224. }
  225.  
  226. int top = 0;
  227. // add a message to the progress list
  228. void
  229. AddMessage(UBYTE *message) {
  230.     struct Node *node;
  231.     if (ProgressWnd) {
  232.         if ((node = (struct Node *)malloc(sizeof(struct Node))) &&
  233.              (node->ln_Name = malloc(strlen(message)+1))) {
  234.             strcpy(node->ln_Name,message);
  235.             GT_SetGadgetAttrs(ProgressGadgets[GDX_Info],ProgressWnd,NULL,
  236.                                  GTLV_Labels, ~0,
  237.                                 TAG_END);
  238.             AddTail(&InfoList,node);
  239.             GT_SetGadgetAttrs(ProgressGadgets[GDX_Info],ProgressWnd,NULL,
  240.                                  GTLV_Labels, &InfoList,
  241.                                  GTLV_MakeVisible, top,
  242.                                 TAG_END);
  243.               top++;
  244.           }
  245.           HandleProgressIDCMP();
  246.     }
  247.     if (ProgressHook) {
  248.         CallHookPkt(ProgressHook,MPIP_MESSAGE,(APTR)message);
  249.     }
  250. }
  251.  
  252. int __stdargs
  253. _STI_CreateSema(void) {
  254. #ifdef CYBER
  255.     char buffer[3];
  256. #endif
  257.     Forbid();
  258.     if (!OpenCount) {
  259.         memset(&sema,0,sizeof(sema));
  260.         InitSemaphore(&sema);
  261.         NewList(&InfoList);
  262.     }
  263.     ++OpenCount;
  264.     Permit();
  265.     if (!(LocaleBase = OpenLibrary("locale.library",38))) {
  266.         return 1;
  267.     }
  268.     Catalog = OpenCatalog(NULL,
  269.                                 "mp/mpimage.catalog",
  270.                                   TAG_END);
  271.     DCTVBase = OpenLibrary("dctv.library",3);
  272. #ifdef CYBER
  273.     if (GetVar("mpimage/cybergraphics",buffer,1,0) != -1) {                            
  274.         CyberGfxBase = OpenLibrary("cybergraphics.library",40);
  275.     }
  276. #endif
  277.     return 0;
  278. }
  279.  
  280. void __stdargs
  281. _STD_DeleteSema(void) {
  282.     --OpenCount;
  283.     if (LocaleBase) {
  284.         CloseCatalog(Catalog);
  285.         Catalog = NULL;
  286.         CloseLibrary(LocaleBase);
  287.         LocaleBase = NULL;
  288.     }
  289.     if (DCTVBase) {
  290.         CloseLibrary(DCTVBase);
  291.         DCTVBase = NULL;
  292.     }
  293. #ifdef CYBER
  294.     if (CyberGfxBase) {
  295.         CloseLibrary(CyberGfxBase);
  296.         CyberGfxBase = NULL;
  297.     }
  298. #endif
  299.     return;
  300. }
  301.  
  302. extern void LockSema(void) {
  303.     ObtainSemaphore(&sema);
  304. }
  305. extern void UnlockSema(void) {
  306.     ReleaseSemaphore(&sema);
  307. }
  308.  
  309. extern void
  310. PlanarToChunky(struct p2cStruct *p2c) {
  311.     AddMessageNo(MSG_P2C);
  312.     ObtainSemaphore(&sema);
  313.     PlanarToChunkyAsm(p2c);
  314.     ReleaseSemaphore(&sema);
  315. }
  316.  
  317. extern void
  318. ChunkyToPlanar(struct c2pStruct *c2p) {
  319.     AddMessageNo(MSG_C2P);
  320.     ObtainSemaphore(&sema);
  321.     ChunkyToPlanarAsm(c2p);
  322.     ReleaseSemaphore(&sema);
  323. }
  324.  
  325. /****** MPImage.library/MPChunkyToPlanar ******************************
  326. *
  327. *   NAME   
  328. *  MPChunkyToPlanar -- Convert a chunky buffer to a BitMap (V7)
  329. *
  330. *   SYNOPSIS
  331. *  MPChunkyToPlanar( chunky, bitmap, width, height )
  332. *                    A0      A1      D0     D1
  333. *
  334. *  void MPPlanarToChunky( UBYTE *, struct BitMap *, UWORD, UWORD);
  335. *
  336. *   FUNCTION
  337. *  Converts a chunky buffer to a BitMap.
  338. *
  339. *   INPUTS
  340. *  chunky - Pointer to a chunky buffer of sufficient size.
  341. *  bitmap - Pointer to a standard bitmap (of sufficient size).
  342. *  width  - Width of buffer.
  343. *  height - Height of buffer.
  344. *
  345. *   RESULT
  346. *  None.
  347. *
  348. *   EXAMPLE
  349. *
  350. *   NOTES
  351. *
  352. *   BUGS
  353. *
  354. *   SEE ALSO
  355. *  MPPlanarToChunky().
  356. *
  357. *****************************************************************************
  358. *
  359. */
  360. void __asm __saveds
  361. MPChunkyToPlanar(register __a0 UBYTE *chunky,register __a1 struct BitMap *bitmap,
  362.                         register __d0 UWORD width, register __d1 UWORD height) {
  363.     struct c2pStruct c2p;
  364.     c2p.bmap = bitmap;
  365.     c2p.startX = 0;
  366.     c2p.startY = 0;
  367.     c2p.width = width;
  368.     c2p.height = height;
  369.     c2p.chunkybuffer = chunky;
  370.     ObtainSemaphore(&sema);
  371.     ChunkyToPlanarAsm(&c2p);
  372.     ReleaseSemaphore(&sema);
  373. }
  374.  
  375. struct MyBitMap *
  376. MyAllocBitMap(UWORD wide,UWORD high, UWORD deep, UBYTE *filename) {
  377.     struct MyBitMap *bitmap;
  378.     int k;
  379.     BOOL error = 0;
  380.  
  381.     if (!filename || !*filename) {
  382.         return (struct MyBitMap *)AllocBitMap(wide,high,deep,BMF_CLEAR|BMF_DISPLAYABLE,NULL);
  383.     }
  384.     if (bitmap = AllocMem(sizeof(struct MyBitMap),MEMF_CLEAR)) {
  385.         InitBitMap((struct BitMap *)bitmap,deep,wide,high);
  386.         for (k=0; k<deep && (!error); k++) {
  387.             if (!(bitmap->BitMap.Planes[k] = AllocVec(RASSIZE(wide,high),MEMF_CLEAR))) {
  388.                 error = 1;
  389.             }
  390.         }
  391.         if(error) {
  392.             MyFreeBitMap(bitmap,filename);
  393.             bitmap = NULL;
  394.         }
  395.     }
  396.     return bitmap;
  397. }
  398.  
  399. void
  400. MyFreeBitMap(struct MyBitMap *bitmap,UBYTE *filename) {
  401.     int k;
  402.     if (!filename || !*filename) {
  403.         FreeBitMap(bitmap);
  404.         return;
  405.     }
  406.     for(k=0; k< bitmap->BitMap.Depth; k++) {
  407.         if (bitmap->BitMap.Planes[k]) {
  408.             FreeVec(bitmap->BitMap.Planes[k]);
  409.         }
  410.     }
  411.     FreeMem(bitmap,sizeof(struct MyBitMap));
  412. }
  413.  
  414. void __asm __saveds FreeMPImage(register __a0 struct MPImage *MPi);
  415.  
  416. char * __asm __saveds MPImageErrorMessage(void);
  417.  
  418. /****** MPImage.library/MPPlanarToChunky ******************************
  419. *
  420. *   NAME   
  421. *  MPPlanarToChunky -- Convert a bitmap to a chunky buffer (V5)
  422. *
  423. *   SYNOPSIS
  424. *  MPPlanarToChunky( bitmap, chunky, width, height )
  425. *                    A0      A1      D0     D1
  426. *
  427. *  void MPPlanarToChunky( struct BitMap *, UBYTE *, UWORD, UWORD);
  428. *
  429. *   FUNCTION
  430. *  Converts a BitMap to a chunky buffer.
  431. *
  432. *   INPUTS
  433. *  bitmap - Pointer to a standard bitmap.
  434. *  chunky - Pointer to a chunky buffer of sufficient size.
  435. *  width  - Width of bitmap.
  436. *  height - Height of bitmap.
  437. *
  438. *   RESULT
  439. *  None.
  440. *
  441. *   EXAMPLE
  442. *
  443. *   NOTES
  444. *
  445. *   BUGS
  446. *
  447. *   SEE ALSO
  448. *  MPChunkyToPlanar().
  449. *
  450. *****************************************************************************
  451. *
  452. */
  453. void __asm __saveds
  454. MPPlanarToChunky(register __a0 struct BitMap *bitmap,register __a1 UBYTE *chunky,
  455.                         register __d0 UWORD width, register __d1 UWORD height) {
  456.     struct p2cStruct p2c;
  457.     p2c.bmap = bitmap;
  458.     p2c.startX = 0;
  459.     p2c.startY = 0;
  460.     p2c.width = width;
  461.     p2c.height = height;
  462.     p2c.chunkybuffer = chunky;
  463.     ObtainSemaphore(&sema);
  464.     PlanarToChunkyAsm(&p2c);
  465.     ReleaseSemaphore(&sema);
  466. }
  467.  
  468.  
  469. /****** MPImage.library/FreeMPImage ***********************************
  470. *
  471. *   NAME   
  472. *  FreeMPImage -- Free an image loaded using LoadMPImage() (V3)
  473. *
  474. *   SYNOPSIS
  475. *  FreeMPImage( MPi )
  476. *               A0
  477. *
  478. *  void FreeMPImage( struct MPImage * );
  479. *
  480. *   FUNCTION
  481. *  Frees all data associated loaded with an image using LoadMPImage().
  482. *
  483. *   INPUTS
  484. *  MPi - structure returned by LoadMPImage().
  485. *
  486. *   RESULT
  487. *  None.
  488. *
  489. *   EXAMPLE
  490. *
  491. *   NOTES
  492. *
  493. *   BUGS
  494. *
  495. *   SEE ALSO
  496. *  LoadMPImage()
  497. *
  498. *****************************************************************************
  499. *
  500. */
  501. void __asm __saveds
  502. FreeMPImage(register __a0 struct MPImage *MPi) {
  503.     if (MPi) {
  504.         if (MPi->Red) {
  505.             FreeVec(MPi->Red);
  506.         }
  507.         if (!MPi->GreyScale) {
  508.             if (MPi->Blue) {
  509.                 FreeVec(MPi->Blue);
  510.             }
  511.             if (MPi->Green) {
  512.                 FreeVec(MPi->Green);
  513.             }
  514.         }
  515.         if (MPi->Object) {    // Dispose object (frees bit map as well...)
  516.             DisposeDTObject(MPi->Object);
  517.         }
  518.         else {
  519.             if (MPi->BitMap) {
  520.                 FreeBitMap(MPi->BitMap);
  521.             }
  522.             if (MPi->EGS_BitMap) {
  523.                 if (EGSBase = OpenLibrary((char *)"egs.library",0)) {
  524.                     E_DisposeBitMap(MPi->EGS_BitMap);
  525.                     CloseLibrary(EGSBase);
  526.                 }
  527.             }
  528.         }
  529.         FreeMem(MPi,sizeof(struct MPImage));
  530.     }
  531. }
  532.  
  533. /****** MPImage.library/MPImageErrorMessage *********************************
  534. *
  535. *   NAME   
  536. *  MPImageErrorMessage -- Return the last error set by MPImage.library. (V3)
  537. *
  538. *   SYNOPSIS
  539. *  msg = MPImageErrorMessage()
  540. *  D0
  541. *
  542. *  char *MPImageErrorMessage( void );
  543. *
  544. *   FUNCTION
  545. *  Returns the last error message set by this opener of MPImage.library.
  546. *
  547. *   INPUTS
  548. *  None.
  549. *
  550. *   RESULT
  551. *  Formatted Error Message.
  552. *
  553. *   EXAMPLE
  554. *
  555. *   NOTES
  556. *
  557. *   BUGS
  558. *
  559. *   SEE ALSO
  560. *
  561. *****************************************************************************
  562. *
  563. */
  564. char * __asm __saveds
  565. MPImageErrorMessage(void) {
  566.     return ErrorMessage;
  567. }
  568.  
  569. extern BOOL ShowProgress;
  570.  
  571. /****** MPImage.library/SetMPImageScreen ************************************
  572. *
  573. *   NAME   
  574. *  SetMPImageScreen -- Sets the Screen name for progress requesters (V3)
  575. *
  576. *   SYNOPSIS
  577. *  SetMPImageScreen(ScreenName,Flags)
  578. *                   A0         D0
  579. *
  580. *  void SetMPImageScreen(char *, ULONG);
  581. *
  582. *   FUNCTION
  583. *  Sets the Screen Name for progress requesters for this opener.
  584. *
  585. *   INPUTS
  586. *  ScreenName - Name of Public Screen, NULL for default
  587. *  Flags      - 0 - Do not show progress requesters (default)
  588. *             - MPIF_PROGRESS - Do show progress requesters
  589. *                               (except for non remapped bitmaps).
  590. *
  591. *   RESULT
  592. *  None.
  593. *
  594. *   EXAMPLE
  595. *
  596. *   NOTES
  597. *  ScreenName must remain valid while MPImage.library is open.
  598. *
  599. *   BUGS
  600. *
  601. *   SEE ALSO
  602. *
  603. *****************************************************************************
  604. *
  605. */
  606. void __asm __saveds
  607. SetMPImageScreen(register __a0 char *ScreenName, register __d0 ULONG Flags) {
  608.     PubScreenName = ScreenName;
  609.     if (Flags & MPIF_PROGRESS) {
  610.         ShowProgress = TRUE;
  611.     }
  612.     else {
  613.         ShowProgress = FALSE;
  614.     }
  615. }
  616.  
  617. /****** MPImage.library/MPProgressHook ************************************
  618. *
  619. *   NAME   
  620. *  MPProgressHook -- Sets the Progress Hook (V6)
  621. *
  622. *   SYNOPSIS
  623. *  MPProgressHook(Hook)
  624. *                 A0
  625. *
  626. *  void MPProgressHook(struct Hook*);
  627. *
  628. *   FUNCTION
  629. *  Sets the Hook to call for progress messages.
  630. *
  631. *   INPUTS
  632. *  Hook - Hook to call
  633. *
  634. *   RESULT
  635. *  None.
  636. *
  637. *   EXAMPLE
  638. *
  639. *   NOTES
  640. *  Called with...
  641. * object = MPIP_MAX, (ULONG)message = max-progress
  642. * object = MPIP_MAX, (ULONG)message = curr-progress
  643. * object = MPIP_CURR,(UBYTE *)message = Progress-Message
  644. *
  645. *   BUGS
  646. *
  647. *   SEE ALSO
  648. *
  649. *****************************************************************************
  650. *
  651. */
  652. void __asm __saveds
  653. MPProgressHook(register __a0 struct Hook *Hook) {
  654.     ProgressHook = Hook;
  655. }
  656.